ReverseSequence

对输入序列进行部分反转。

输入:
  • src - 需反转数据的地址

  • seq_lengths - 指定反转长度,为一维向量。

  • param - 算子计算所需参数的结构体。其各成员见下述。

  • core_mask - 核掩码(仅共享存储版本使用)。

ReverseSequenceParameter定义:

 1typedef struct ReverseSequenceParameter {
 2    int* shape_; // 输入和输出张量的形状
 3    int* strides_; // 一个记录张量每一维步长的数组
 4    int seq_dim_; // 指定反转的维度
 5    int batch_dim_; // 指定切片维度
 6    int ndim_; // 输入和输出张量的维度
 7    int copy_elem_num_; // 在inner_count循环中一次应被拷贝的元素数目
 8    int outer_stride_; // 外层元素间的步长
 9    int outer_count_; // 外层元素数
10    int inner_stride_; // 内层元素间的步长
11    int inner_count_; // 内层元素数
12} ReverseSequenceParameter;
输出:
  • dst - 输出地址。

支持平台:

FT78NE MT7004

备注

  • FT78NE 支持int8, int16, int32, fp32, fp64, cplx64, cplx128

  • MT7004 支持fp16, fp32, int16, int32, cplx64

共享存储版本:

void i8_reverse_sequence_s(int8_t *src, int8_t *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)
void i16_reverse_sequence_s(int16_t *src, int16_t *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)
void i32_reverse_sequence_s(int32_t *src, int32_t *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)
void hp_reverse_sequence_s(float16 *src, float16 *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)
void fp_reverse_sequence_s(float *src, float *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)
void dp_reverse_sequence_s(double *src, double *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)
void c64_reverse_sequence_s(float *src, float *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)
void c128_reverse_sequence_s(double *src, double *dst, int *seq_lengths, ReverseSequenceParameter *param, int core_mask)

C调用示例:

 1// MT7004 示例(共享存储多核,DDR 地址)
 2void Resize(ReverseSequenceParameter* param) {
 3    int less_dim = param->batch_dim_ > param->seq_dim_ ? param->seq_dim_ : param->batch_dim_;
 4    int greater_dim = param->batch_dim_ < param->seq_dim_ ? param->seq_dim_ : param->batch_dim_;
 5    int i;
 6    // calculate the size of elements should be copied at one time
 7    param->copy_elem_num_ = CountElementAfterDim(param->shape_, greater_dim, param->ndim_);
 8    // calculate the number of elements before the less axis and the stride
 9    param->outer_count_ = CountElementBeforeDim(param->shape_, less_dim);
10    param->outer_stride_ = param->shape_[less_dim] * CountElementAfterDim(param->shape_, less_dim, param->ndim_);
11    // calculate the number of elements between the less axis and the greater axis and the stride
12    param->inner_count_ = 1;
13    for (i = less_dim + 1; i < greater_dim; i++) {
14        param->inner_count_ *= param->shape_[i];
15    }
16    param->inner_stride_ = param->shape_[greater_dim] * CountElementAfterDim(param->shape_, greater_dim, param->ndim_);
17    ComputeStrides(param->shape_, param->strides_, param->ndim_);
18}
19
20void TestReverseSequenceFp32(int* shape, int* orig_seq_lengths, int seq_dim, int batch_dim, int ndim, int core_mask) {
21    int core_id = get_core_id();
22    int core_num = GetCoreNum(core_mask);
23    int logic_core_id = GetLogicCoreId(core_mask, core_id);
24    float* input_data = (float*)0x88000000;
25    float* output_data = (float*)0x98000000;
26    int* seq_lengths = (int*)0xC0000000;
27    ReverseSequenceParameter* param = (ReverseSequenceParameter*)0xC0001000;
28    if (logic_core_id == 0) {
29        param->shape_ = (int*)0xC0002000;
30        param->strides_ = (int*)0xC0003000;
31        memcpy(param->shape_, shape, sizeof(int) * ndim);
32        memcpy(seq_lengths, orig_seq_lengths, sizeof(int) * shape[batch_dim]);
33        param->batch_dim_ = batch_dim;
34        param->seq_dim_ = seq_dim;
35        param->ndim_ = ndim;
36        Resize(param);
37    }
38    sys_bar(0, core_num); // 初始化参数完成后进行同步
39    fp_reverse_sequence_s(input_data, output_data, seq_lengths, param, core_mask);
40}
41
42void main(){
43    int shape[3] = {3, 4, 10};
44    int seq_lengths[3] = {1, 2, 3};
45    int ndim = 3;
46    int seq_dim = 1;
47    int batch_dim = 0;
48    int core_mask = 0b1111;
49    TestReverseSequenceFp32(shape, seq_lengths, seq_dim, batch_dim, ndim, core_mask);
50}

私有存储版本:

void i8_reverse_sequence_p(int8_t *src, int8_t *dst, int *seq_lengths, ReverseSequenceParameter *param)
void i16_reverse_sequence_p(int16_t *src, int16_t *dst, int *seq_lengths, ReverseSequenceParameter *param)
void i32_reverse_sequence_p(int32_t *src, int32_t *dst, int *seq_lengths, ReverseSequenceParameter *param)
void hp_reverse_sequence_p(float16 *src, float16 *dst, int *seq_lengths, ReverseSequenceParameter *param)
void fp_reverse_sequence_p(float *src, float *dst, int *seq_lengths, ReverseSequenceParameter *param)
void dp_reverse_sequence_p(double *src, double *dst, int *seq_lengths, ReverseSequenceParameter *param)
void c64_reverse_sequence_p(float *src, float *dst, int *seq_lengths, ReverseSequenceParameter *param)
void c128_reverse_sequence_p(double *src, double *dst, int *seq_lengths, ReverseSequenceParameter *param)

C调用示例:

 1// MT7004 示例(私有存储单核,AM 地址)
 2void TestReverseSequenceFp32_p(int* shape, int* orig_seq_lengths, int seq_dim, int batch_dim, int ndim) {
 3    float* input_data = (float*)0x10000000;
 4    float* output_data = (float*)0x10020000;
 5    int* seq_lengths = (int*)0x10060000;
 6    ReverseSequenceParameter* param = (ReverseSequenceParameter*)0x10061000;
 7
 8    param->shape_ = (int*)0x10062000;
 9    param->strides_ = (int*)0x10063000;
10    memcpy(param->shape_, shape, sizeof(int) * ndim);
11    memcpy(seq_lengths, orig_seq_lengths, sizeof(int) * shape[batch_dim]);
12    param->batch_dim_ = batch_dim;
13    param->seq_dim_ = seq_dim;
14    param->ndim_ = ndim;
15    Resize(param);
16
17    fp_reverse_sequence_p(input_data, output_data, seq_lengths, param);
18}
19
20void main(){
21    int shape[3] = {2, 4, 32};
22    int seq_lengths[2] = {1, 2};
23    int ndim = 3;
24    int seq_dim = 1;
25    int batch_dim = 0;
26    TestReverseSequenceFp32_p(shape, seq_lengths, seq_dim, batch_dim, ndim);
27}